/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
/**
 * Software License, Version 1.0
 *
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 *
 *
 *Redistribution and use in source and binary forms, with or without
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For
 * further information contact the Community Grids Lab at
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and
 * wherever such third-party acknowledgments normally appear.
 *
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering,
 * shall not be used to endorse or promote products derived from this software
 * without prior written permission from Indiana University.  For written
 * permission, please contact the Advanced Research and Technology Institute
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering,
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 *
 *
 * Indiana University provides no reassurances that the source code provided
 * does not infringe the patent or any other intellectual property rights of
 * any other entity.  Indiana University disclaims any liability to any
 * recipient for claims brought by any other entity based on infringement of
 * intellectual property rights or otherwise.
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS.
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS",
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.transport.ptcp;



import cgl.narada.transport.Link;
import cgl.narada.transport.MonitoredLink;
import cgl.narada.transport.TransportDebugFlags;
import cgl.narada.transport.TransportException;
import cgl.narada.transport.TransportHandler;
import cgl.narada.transport.ptcp.psocket.PTCPSocket;


/** This is a TCP implementation of the Link interface. Say we are trying to
    establish a communication from node A to node B. To create links one needs
    following properties to be specified.
    <li><b>hostname</b>: This is the hostname on which the node B's process is
    running.
    <li><b>portnum</b>: This is the port number on which node B accepts link
    creation requests from other nodes. In other words, the <i>TCPServerPort
    </i> specified to the TCPChannelFactory at node B is equal to portnum.

    @author Shrideep Pallickara
    $Date$
    $Revision$
*/

public class PTCPLink extends MonitoredLink
  implements Link, TransportDebugFlags {
  private String linkId;
  private Object naradaBrokeringId;
  private String linkType="ptcp";
  private boolean secure = false;
  private String securityInformation =
  "Communication on this link is not encrypted";
  private boolean connectionLost=false;
  private boolean linkClosed= false;
  private String moduleName = "PTCPLink: ";
 // private Socket socket; //remove this later
  private PTCPSocket psocket;
  private PTCPSenderThread sender;
  private PTCPReceiverThread receiver;
  private PTCPLinkFactory ptcpLinkFactory;
  private TransportHandler transportHandler;



  public PTCPLink(PTCPSocket psocket, PTCPLinkFactory ptcpLinkFactory)
    throws TransportException {
    this.transportHandler = ptcpLinkFactory.getTransportHandler();
    receiver = new PTCPReceiverThread(psocket, this);
    sender = new PTCPSenderThread(psocket, this);
    this.ptcpLinkFactory = ptcpLinkFactory;

    if (PTCPLink_Debug) {
      System.out.println(moduleName +"Initialization complete");
    }

    String _host = psocket.getInetAddress().getHostName();
    int _port = psocket.getPort();
    String _key = _host +":" + _port;
    receiver.setLinkId(_key);
    //receiver.start();
    sender.start();
  }

  public void startLinkServices() {
    receiver.start();
  }

  /** The method used to send data over a communication link */
  public void sendData(byte[] data) throws TransportException {
    if (PTCPLink_Debug) {
      System.out.println(moduleName + "Sending data");
    }
    sender.sendData(data);
  }

  /** The method used to send data over a communication link, this method
      also includes information regarding the type (audio/video/xml-attachments
      etc.) of the data encapsulated within the data stream. Using this
      information links can optimally flush/send data across the link
  */
  public void sendData(byte[] data, String dataType)
    throws TransportException {
    sender.sendData(data, dataType);
  }

  /** Sets the Id of the communication link */
  public void setLinkId(String stringId) {
    this.linkId = stringId;
    receiver.setLinkId(stringId);
  }

  /** Retrieves the String based id of the link */
  public String getLinkId() {
    return linkId;
  }

  /** The Naradabrokering Id of the node this link interacts with */
  public void setNaradaBrokeringId(Object brokeringId) {
    naradaBrokeringId = brokeringId;
  }

  /** Returns the NaradaBrokeringId associated with this link */
  public Object getNaradaBrokeringId() {
    return naradaBrokeringId;
  }

  /** Returns the type of the communication link */
  public String getLinkType() {
    return linkType;
  }

  /** Sets the conditions under which communication protocols need to be
      switched and the transport link that it should be switched to under
      the condition. Multiple constraints can be set signifying migration to
      different protocols.  */
  public void setLinkMigrationConstraint(String constraint,
					    String linkType) {
    /**NBNI*/
  }

  /** Check the status of the communication link at intervals specified in
      the argument of this method */
  public void setLinkStatusInterval(long interval) {
    /**NBNI*/
  }

  /** Set the amount of time after which resources associated with this
      link need to be garbage collected. A value of '0' indicates that
      this link needs to be active at all times. */
  public void setKeepAliveTime(long keepAliveTime) {
    /**NBNI*/
  }

  /** Garbage collect resources associated with this link. Sockets need to
      be closed and any resources associated with communication, needs to be
      garbage collected */
  public void closeLink() {
    linkClosed = true;
    receiver.releaseResources();
    //sender.releaseResources();
    ptcpLinkFactory.reportLinkLoss(this);
  }

  /** Indicates weather communication is encrypted on this link */
  public boolean isSecure() {
    return secure;
  }

  /** Information pertaining to the security strategy adopted for this
      communication link */
  public String getSecurityInformation() {
    return securityInformation;
  }

  /** If the senderNotification is false, it implies that the detection of
      connection loss has been reported by the receiver thread. Proceed to
      garbage collect the sender thread.
      If the boolean variable is true, it implies that the receiver thread
      has to be garbage collected. */
  public void processLossOfSocketConnection(boolean senderNotification) {
    if (linkClosed) {
      /** No need to do further processing */
      return;
    }

    if (connectionLost) {
      /** The loss was connection has been detected earlier, and the
	  associated garbage collection operations are being performed */
      return;
    }

    if (senderNotification) {
      System.out.println(moduleName + "Connection loss reported by PTCPSender");
      receiver.releaseResources();
    } else {
      System.out.println(moduleName+"Connection loss reported by PTCPReceiver");
      sender.releaseResources();
    }
    connectionLost = true;
    ptcpLinkFactory.reportLinkLoss(this);

    System.out.println(moduleName +
		       "Processing of communication loss on link ["   +
		       linkId + "] complete");
  }


  public TransportHandler getTransportHandler() {
    return transportHandler;
  }

}

